﻿using Modules.SMS;
using NPOI.SS.Formula.Functions;
using PmSoft.Utilities;
using System;
using System.Security.Principal;
using System.Xml.Linq;

namespace ManagementApi.TreeParty.SMS
{
    public class SmsTemplate
    {
        public string Content { get; set; }
        public string TemplateCode { get; set; }
    }

    /// <summary>
    /// 短信生成器
    /// </summary>
    public class SmsBuidler
    {
        #region Instance

        private static volatile SmsBuidler _instance = null;
        private static readonly object lockObject = new object();

        public static SmsBuidler Instance()
        {
            if (_instance == null)
            {
                lock (lockObject)
                {
                    if (_instance == null)
                    {
                        _instance = new SmsBuidler();
                    }
                }
            }
            return _instance;
        }

        private SmsBuidler()
        {
            Templates = LoadTemplates();
        }

        #endregion Instance

        #region Templates

        public Dictionary<string, SmsTemplate> Templates { get; private set; }

        private Dictionary<string, SmsTemplate> LoadTemplates()
        {
            var templates = new Dictionary<string, SmsTemplate>();

            string templateFileName = Path.Combine("Config", "SmsTemplates.xml");
            if (!File.Exists(templateFileName))
                throw new FileNotFoundException(nameof(templateFileName));

            XElement xElement = XElement.Load(templateFileName);
            XElement rootEle = xElement.Element("templates");

            foreach (XElement element in rootEle.Elements("template"))
            {
                var att = element.Attribute("templateName");
                string templateName = string.Empty;
                if (att != null)
                    templateName = att.Value;
                if (templates.ContainsKey(templateName))
                    continue;

                att = element.Attribute("templateCode");
                string templateCode = string.Empty;
                if (att != null)
                    templateCode = att.Value;

                SmsTemplate template = new SmsTemplate
                {
                    Content = element.Value.Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", ""),
                    TemplateCode = templateCode
                };
                templates.Add(templateName, template);
            }
            return templates;
        }

        #endregion Templates

        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <returns></returns>
        public string GetValidateCode()
        {
            Random random = new Random();
            return random.Next(1000, 10000).ToString();
        }

        /// <summary>
        /// 验证码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public SmsModel ValidateCode(string code = "")
        {
            SmsTemplate template;
            Templates.TryGetValue("ValidateCode", out template);
            if (template == null)
                throw new NullReferenceException(nameof(template));

            var model = SmsModel.New(MsgType.VerificationCode);
            model.TemplateCode = template.TemplateCode;
            model.Code = code;
            SafeMap<string> maps = new SafeMap<string>();
            maps.Set("Code", code);
            model.Message = TemplateUtility.ReplacePlaceholder(template.Content, maps);
            model.TemplateParams = maps;
            return model;
        }

        /// <summary>
        /// 改变劳资专管员
        /// </summary>
        /// <param name="projectName"></param>
        /// <param name="projectNum"></param>
        /// <param name="account"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public SmsModel ChangeProjectManager(string projectName, string projectNum, string account = "", string password = "")
        {
            SmsTemplate template;
            if (string.IsNullOrEmpty(account))
            {
                Templates.TryGetValue("ChangeProjectManager", out template);
            }
            else
            {
                Templates.TryGetValue("ChangeProjectManagerNew", out template);
            }

            if (template == null)
                throw new NullReferenceException(nameof(template));

            var model = SmsModel.New(MsgType.ChangeProjectManager);
            model.TemplateCode = template.TemplateCode;
            SafeMap<string> maps = new SafeMap<string>();
            maps.Set("ProjectName", projectName);
            maps.Set("ProjectNum", projectNum);
            maps.Set("Account", account);
            maps.Set("Password", password);
            model.Message = TemplateUtility.ReplacePlaceholder(template.Content, maps);
            model.TemplateParams = maps;
            return model;
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="account"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public SmsModel ResetPassword(string account = "", string password = "")
        {
            SmsTemplate template;
            Templates.TryGetValue("ResetPassword", out template);
            if (template == null)
                throw new NullReferenceException(nameof(template));

            var model = SmsModel.New(MsgType.ResetPassword);
            model.TemplateCode = template.TemplateCode;
            SafeMap<string> maps = new SafeMap<string>();
            maps.Set("Account", account);
            maps.Set("Password", password);
            model.Message = TemplateUtility.ReplacePlaceholder(template.Content, maps);
            model.TemplateParams = maps;
            return model;
        }

        /// <summary>
        /// 企业审核成功
        /// </summary>
        /// <param name="corpName"></param>
        /// <param name="corpCode"></param>
        /// <returns></returns>
        public SmsModel CorpVerifySuccess(string corpName, string corpCode)
        {
            SmsTemplate template;
            Templates.TryGetValue("CorpVerifySuccess", out template);
            if (template == null)
                throw new NullReferenceException(nameof(template));

            var model = SmsModel.New(MsgType.CorpVerifySuccess);
            model.TemplateCode = template.TemplateCode;
            SafeMap<string> maps = new SafeMap<string>();
            maps.Set("CorpName", corpName);
            maps.Set("CorpCode", corpCode);
            model.Message = TemplateUtility.ReplacePlaceholder(template.Content, maps);
            model.TemplateParams = maps;
            return model;
        }

        /// <summary>
        /// 企业审核失败
        /// </summary>
        /// <param name="corpName"></param>
        /// <param name="corpCode"></param>
        /// <returns></returns>
        public SmsModel CorpVerifyFail(string corpName, string corpCode)
        {
            SmsTemplate template;
            Templates.TryGetValue("CorpVerifyFail", out template);
            if (template == null)
                throw new NullReferenceException(nameof(template));

            var model = SmsModel.New(MsgType.CorpVerifyFail);
            model.TemplateCode = template.TemplateCode;
            SafeMap<string> maps = new SafeMap<string>();
            maps.Set("CorpName", corpName);
            maps.Set("CorpCode", corpCode);
            model.Message = TemplateUtility.ReplacePlaceholder(template.Content, maps);
            model.TemplateParams = maps;
            return model;
        }
    }
}